using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;

namespace Luka;

/// <summary>
/// 内部静态值
/// </summary>
[NotScanned]
internal static class InternalApp
{
    /// <summary>
    /// 用户信息
    /// </summary>
    public static object? User;

    /// <summary>
    /// 用户类型
    /// </summary>
    public static Type? UserType { get; set; }

    /// <summary>
    /// 存储根服务，可能为空
    /// </summary>
    public static IServiceProvider? RootServices;

    /// <summary>
    /// 配置项
    /// </summary>
    public static IConfiguration? RootConfiguration => new ConfigurationBuilder().Build();

    /// <summary>
    /// 当前环境名称
    /// </summary>
    public static string EnvironmentName => Environment.GetEnvironmentVariables()["ASPNETCORE_ENVIRONMENT"]?.ToString() ?? "";

    /// <summary>
    /// 当前程序集名称
    /// </summary>
    public static string ProgramName => AppDomain.CurrentDomain.FriendlyName;

    /// <summary>
    /// 提供有关应用程序域基础目录的信息的属性
    /// </summary>
    public static string CurrentDomainPath => AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;

    /// <summary>
    /// 根据dll获取所有类型
    /// </summary>
    /// <returns></returns>
    public static IEnumerable<Type> TypeList => Directory.GetFiles(CurrentDomainPath, "*.dll")
                     .Select(Assembly.LoadFrom)
                     .SelectMany(a => a.DefinedTypes)
                     .Where(it => !it.IsDefined(typeof(NotScannedAttribute), false))
                     .Select(type => type.AsType());

    /// <summary>
    /// 根据dll获取类型
    /// </summary>
    /// <typeparam name="Ttype">类型</typeparam>
    /// <returns></returns>
    public static Type? GetType<Ttype>() where Ttype : class => TypeList.FirstOrDefault(it => it == typeof(Ttype));

    /// <summary>
    ///  获取服务
    /// </summary>
    /// <typeparam name="TService">服务类型</typeparam>
    /// <returns></returns>
    public static TService? GetService<TService>() where TService : class => RootServices?.GetService<TService>();

    /// <summary>
    /// 判断配置是否存在
    /// </summary>
    /// <param name="key">键名</param>
    /// <returns>是否存在</returns>
    public static bool Exists(string key)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            return false;
        }
        return RootConfiguration?.GetSection(key).Exists() == true;
    }

    /// <summary>
    /// 获取config文件信息
    /// </summary>
    /// <param name="key">键名</param>
    /// <returns></returns>
    public static string GetSection(string key)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            return string.Empty;
        }
        return RootConfiguration?.GetValue<string>(key) ?? string.Empty;
    }

    /// <summary>
    /// 获取config文件信息
    /// </summary>
    /// <typeparam name="TOptions">泛型类型</typeparam>
    /// <param name="key">键名</param>
    /// <returns></returns>
    public static TOptions GetSection<TOptions>(string key) where TOptions : class, new()
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            return new TOptions();
        }
        return RootConfiguration?.GetSection(key).Get<TOptions>() ?? new TOptions();
    }
}